#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional, NoReturn,List
from loguru import logger
from datetime import datetime

from sqlalchemy import func, select, update, delete, desc
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.sql import Select

from app.api import jwt
from app.models import User
from app.schemas.user import CreateUser, DeleteUser, UpdateUser

from app.utils.script_powershell import login_by_powershell 


async def get_users(db: AsyncSession) -> List[User]:
    users = await db.execute(select(User))
    return users.scalars().all()


async def get_user_by_id(db: AsyncSession, user_id: int) -> Optional[User]:
    user = await db.execute(select(User).where(User.id == user_id))
    return user.scalars().first()


async def get_user_by_loginid(db: AsyncSession, loginid: str) -> Optional[User]:
    user = await db.execute(select(User).where(User.loginid == loginid))
    return user.scalars().first()



async def update_user_roles_by_id(db: AsyncSession, id: int,roles:List[str]) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == id)
        .values({
            User.roles:roles
        })
    )
    return user.rowcount



# update time每次要手动更新,
async def update_user_login_time(db: AsyncSession, loginid: str) -> int:
    """更新登录时间，但是不要使用sqlite里面func.now(),时区不对，使用datetime.now()

    Args:
        db (AsyncSession): _description_
        loginid (str): _description_

    Returns:
        int: _description_
    """
    user = await db.execute(
        update(User)
        .where(User.loginid == loginid)
        .values(last_login=datetime.now())
    )
    await db.commit()
    return user.rowcount



async def get_email_by_username(db: AsyncSession, username: str) -> str:
    user = await get_user_by_loginid(db, username)
    return user.email


async def get_username_by_email(db: AsyncSession, email: str) -> str:
    user = await db.execute(select(User).where(User.email == email))
    return user.scalars().first().username


async def get_avatar_by_username(db: AsyncSession, username: str) -> str:
    user = await db.execute(select(User).where(User.username == username))
    return user.scalars().first().avatar


# async def create_user(db: AsyncSession, create: CreateUser) -> NoReturn:
#     create.password = jwt.get_hash_password(create.password)
#     new_user = User(**create.dict())
#     db.add(new_user)

async def create_user(db: AsyncSession, create: CreateUser) -> NoReturn:
    new_user = User(**create.dict())
    db.add(new_user)
    await db.commit()

async def create_user_from_auo(db: AsyncSession, loginid:str) -> NoReturn:
    res = login_by_powershell(loginid)
    if len(res.get('resData'))==0:
        return None
    user_info = res.get('resData')[0]
    await create_user(db,CreateUser(**user_info))


async def update_userinfo(db: AsyncSession, current_user: User, obj: UpdateUser) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == current_user.id)
        .values(**obj.dict())
    )
    return user.rowcount


async def update_avatar(db: AsyncSession, current_user: User, avatar: str) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == current_user.id)
        .values(avatar=avatar)
    )
    return user.rowcount


async def delete_user(db: AsyncSession, user_id: DeleteUser) -> int:
    user = await db.execute(delete(User).where(User.id == user_id))
    return user.rowcount


async def check_email(db: AsyncSession, email: str) -> User:
    mail = await db.execute(select(User).where(User.email == email))
    return mail.scalars().first()


async def delete_avatar(db: AsyncSession, user_id: int) -> int:
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(avatar=None)
    )
    return user.rowcount


async def reset_password(db: AsyncSession, username: str, password: str) -> int:
    user = await db.execute(
        update(User)
        .where(User.username == username)
        .values(password=jwt.get_hash_password(password))
    )
    return user.rowcount


# def get_users() -> Select:
#     return select(User).order_by(desc(User.time_joined))


async def get_user_is_super(db: AsyncSession, user_id: int) -> bool:
    user = await get_user_by_id(db, user_id)
    return user.is_superuser


async def get_user_is_active(db: AsyncSession, user_id: int) -> bool:
    user = await get_user_by_id(db, user_id)
    return user.is_active


async def super_set(db: AsyncSession, user_id: int) -> int:
    super_status = await get_user_is_super(db, user_id)
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(is_superuser=False if super_status else True)
    )
    return user.rowcount


async def active_set(db: AsyncSession, user_id: int) -> int:
    active_status = await get_user_is_active(db, user_id)
    user = await db.execute(
        update(User)
        .where(User.id == user_id)
        .values(is_active=False if active_status else True)
    )
    return user.rowcount



async def get_employees_by_boss_loginid(db: AsyncSession, boss_loginid: int)-> Optional[User]:
    user = await db.execute(select(User).where(User.boss_loginid == boss_loginid))
    return user.scalars().all()

